package com.tianci.appstore.ui.detail;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;

import com.coocaa.x.framework.utils.LogUtils;
import com.tianci.appstore.R;
import com.tianci.appstore.ui.SkinManager;
import com.tianci.appstore.utils.SkyConstants;
import com.tianci.appstore.utils.SkyNetImageCache;
import com.tianci.appstore.utils.SkyNetImageCache.ImageLoadListener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class ShotsScrollView extends LinearLayout {
    private Context context;
    private ImageLoadListener imageLoadListener;
    private OnClickListener imageClickListener;
    private ShotLoseFocusListener focusListener;

    private int shotsWidth = SkyConstants.Div(634);
    private int shotsHeight = SkyConstants.Div(386);
    private int spacing = SkyConstants.Div(-50);
    private final int maxShotsPerPage = 3;

    private int shotsCount;
    private int scrollLeftIndex = 0;
    private final int duration = 50;

    private FrameLayout mainLayout;
    private ImageView leftArrow;
    private ImageView rightArrow;

    private ArrayList<Bitmap> bmList;
    private HashMap<Integer, Bitmap> bmMap;

    private int lastKey;

    public ShotsScrollView(Context context, ImageLoadListener listener) {
        super(context);
        this.context = context;
        this.imageLoadListener = listener;
        this.setGravity(Gravity.CENTER_VERTICAL);

        bmList = new ArrayList<Bitmap>();
        bmMap = new HashMap<Integer, Bitmap>();

        leftArrow = new ImageView(context);
        rightArrow = new ImageView(context);
        SkinManager.setBackground(leftArrow, R.drawable.left_arrow);
        SkinManager.setBackground(rightArrow, R.drawable.right_arrow);

        mainLayout = new FrameLayout(context);
        LinearLayout.LayoutParams shotsParams = new LinearLayout.LayoutParams(SkyConstants.Div(1802), shotsHeight);
//        shotsParams.leftMargin = SkyConstants.Div(20);
//        shotsParams.rightMargin = SkyConstants.Div(20);

        this.addView(leftArrow);
        this.addView(mainLayout, shotsParams);
        this.addView(rightArrow);
    }

    public void setShotsUrl(List<String> shotsUrlList) {
        if (shotsUrlList == null) {
            shotsCount = 0;
            return;
        }

        shotsCount = shotsUrlList.size();
        if (shotsCount > AppDetailView.MAX_SHOT_COUNT)
            shotsCount = AppDetailView.MAX_SHOT_COUNT;
        ImageView lastImage = null;
        for (int i = 0; i < shotsCount; i++) {
            LogUtils.d("shot", "url_" + i + " = " + shotsUrlList.get(i));
            ImageView previewImage = null;
            if (i < mainLayout.getChildCount()) {
                previewImage = (ImageView) mainLayout.getChildAt(i);
            } else {
                previewImage = new ImageView(context);
                previewImage.setScaleType(ScaleType.CENTER_INSIDE);
                previewImage.setImageDrawable(SkinManager.getResDrawable(R.drawable.pic_nopic));
                SkinManager.setBackground(previewImage, R.drawable.block_bg);
                previewImage.setPadding(SkyConstants.shadowWidth, SkyConstants.shadowWidth, SkyConstants.shadowWidth, SkyConstants.shadowWidth);
                previewImage.setFocusable(true);
                previewImage.setTag(i);
                previewImage.setId(i);
                previewImage.setOnFocusChangeListener(new OnFocusChangeListener() {
                    @Override
                    public void onFocusChange(View v, boolean hasFocus) {
                        // 如果使用安卓默认的焦点设置，可能将焦点设至屏幕上已经不可见的ImageView上
                        // 会让用户误以为焦点丢失，需要自己手动控制焦点
                        // TODO Auto-generated method stub
                        if (hasFocus) {
                            if (lastKey != KeyEvent.KEYCODE_DPAD_LEFT && lastKey != KeyEvent.KEYCODE_DPAD_RIGHT) {
                                lastKey = KeyEvent.KEYCODE_DPAD_LEFT;
                                int index = (Integer) v.getTag() + scrollLeftIndex;
                                if (index >= mainLayout.getChildCount())
                                    index = scrollLeftIndex;
                                if (index != (Integer) v.getTag()) {
                                    View newV = mainLayout.getChildAt(index);
                                    v.clearFocus();
                                    newV.requestFocus();
                                } else
                                    SkinManager.setBackground(v, R.drawable.block_focused);

                            } else
                                SkinManager.setBackground(v, R.drawable.block_focused);
                        } else
                            SkinManager.setBackground(v, R.drawable.block_bg);
                        v.setPadding(SkyConstants.shadowWidth, SkyConstants.shadowWidth, SkyConstants.shadowWidth, SkyConstants.shadowWidth);
                    }
                });
                if (imageClickListener != null)
                    previewImage.setOnClickListener(imageClickListener);
                previewImage.setOnKeyListener(new OnKeyListener() {
                    @Override
                    public boolean onKey(View v, int keyCode, KeyEvent event) {
                        // TODO Auto-generated method stub
                        LogUtils.d("image_key", "image onkey");
                        lastKey = keyCode;
                        if (event.getAction() == KeyEvent.ACTION_UP)
                            return false;
                        if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
                            int vId = (Integer) v.getTag();
                            if (vId > 0 && keyCode == KeyEvent.KEYCODE_DPAD_LEFT && vId <= scrollLeftIndex) {
                                flipPrev();
                            } else if (vId < shotsCount - 1
                                    && vId - scrollLeftIndex >= maxShotsPerPage - 1
                                    && keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
                                flipNext();
                            }
                        }
                        if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
                            int vId = (Integer) v.getTag();
                            if (focusListener != null) {
                                focusListener.loseFocus(vId - scrollLeftIndex);
                                return true;
                            }
                        }
                        return false;
                    }
                });
                if (i >= maxShotsPerPage)
                    previewImage.setAlpha(0.0f);
                else
                    previewImage.setAlpha(1.0f);
                FrameLayout.LayoutParams shotParams = new FrameLayout.LayoutParams(shotsWidth, shotsHeight);
                int leftIndex = i > maxShotsPerPage ? maxShotsPerPage : i;
                shotParams.leftMargin = leftIndex * (shotsWidth + spacing);
                mainLayout.addView(previewImage, shotParams);
            }
            SkyNetImageCache.getSkyNetImageCache().downloadSreenShot(false,
                    shotsUrlList.get(i), imageLoadListener);

            if (lastImage != null) {
                lastImage.setNextFocusRightId(previewImage.getId());
                previewImage.setNextFocusLeftId(lastImage.getId());
            }
            lastImage = previewImage;
        }
        if (mainLayout.getChildCount() > shotsCount) {
            mainLayout.removeViews(shotsCount, mainLayout.getChildCount() - shotsCount);
        }
        scrollLeftIndex = 0;
        refreshArrow();
    }

    public void setImageClickListener(OnClickListener listener) {
        this.imageClickListener = listener;
    }

    private void refreshArrow() {
        if (scrollLeftIndex == 0)
            leftArrow.setVisibility(View.INVISIBLE);
        else
            leftArrow.setVisibility(View.VISIBLE);
        if (scrollLeftIndex + maxShotsPerPage >= shotsCount)
            rightArrow.setVisibility(View.INVISIBLE);
        else
            rightArrow.setVisibility(View.VISIBLE);
    }

    public ImageView getChildAtIndex(int index) {
        View v = mainLayout.getChildAt(index);
        return (ImageView) v;
    }

    private void flipPrev() {
        int index = 0, xPos = 0;
        for (int i = -1; i < maxShotsPerPage; i++) {
            index = i + scrollLeftIndex;
            View v = mainLayout.getChildAt(index);
            if (v == null)
                continue;
            int leftIndex = index + 1 - scrollLeftIndex;
            if (leftIndex < -1)
                leftIndex = -1;
            else if (leftIndex > maxShotsPerPage)
                leftIndex = maxShotsPerPage;
            xPos = leftIndex * (shotsWidth + spacing);
            if (i == -1) {
                v.animate().x(xPos).y(0).alpha(1.0f).setDuration(duration);
            } else if (i == maxShotsPerPage - 1) {
                v.animate().x(xPos).y(0).alpha(0).setDuration(duration);
            } else {
                v.animate().x(xPos).y(0).setDuration(duration);
            }
        }
        scrollLeftIndex--;
        refreshArrow();
    }

    private void flipNext() {
        int index = 0, xPos = 0;
        for (int i = 0; i <= maxShotsPerPage; i++) {
            index = i + scrollLeftIndex;
            View v = mainLayout.getChildAt(index);
            if (v == null)
                continue;
            int leftIndex = index - 1 - scrollLeftIndex;
            if (leftIndex < -1)
                leftIndex = -1;
            else if (leftIndex > maxShotsPerPage)
                leftIndex = maxShotsPerPage;
            xPos = leftIndex * (shotsWidth + spacing);
            if (i == 0) {
                v.animate().x(xPos).y(0).alpha(0).setDuration(duration);
            } else if (i == maxShotsPerPage) {
                v.animate().x(xPos).y(0).alpha(1.0f).setDuration(duration);
            } else {
                v.animate().x(xPos).y(0).setDuration(duration);
            }
        }
        scrollLeftIndex++;
        refreshArrow();
    }

    public void imageLoaded(int index, Bitmap bm) {
        bmList.add(bm);
        bmMap.put(index, bm);
        ImageView shotImage = (ImageView) getChildAtIndex(index);
        if (shotImage != null) {
            shotImage.setScaleType(ScaleType.FIT_XY);
            shotImage.setImageBitmap(bm);
        }
    }

    public void recycleBitmaps() {
        for (int i = 0; i < shotsCount; i++) {
            ImageView previewImage = (ImageView) mainLayout.getChildAt(i);
            if (previewImage != null) {
                previewImage.setImageDrawable(SkinManager.getResDrawable(R.drawable.pic_nopic));
            }
        }
        bmMap.clear();
        if (bmList.size() > 0) {
            Bitmap bm = null;
            for (int i = bmList.size() - 1; i >= 0; i--) {
                bm = bmList.get(i);
                bmList.remove(bm);
                bm.recycle();
                bm = null;
            }
            bmList.clear();
        }
    }

    public Bitmap getBitmapByIndex(int index) {
        if (bmMap != null)
            return bmMap.get(index);
        return null;
    }

    public void setShotLostFocusListener(ShotLoseFocusListener listener) {
        this.focusListener = listener;
    }

    public interface ShotLoseFocusListener {
        public void loseFocus(int index);
    }
}
